レイトレーシング: レイ
#レイトレーシング #ベクトル
https://gyazo.com/d6a55f0f9fce0e5951e00c89dc790283
Source: https://www.shadertoy.com/view/mt3GW7
本ページは、レイトレーシング(レイマーチングを含む)におけるレイの生成処理を取り扱う
レイトレーシングが描画範囲とするディスプレイ上の各ピクセルに対してレイを生成する
基本
レイを定義する際、レイの始点 (ray origin) と方向 (ray direction) の定義が必要
透視投影
例えば、右手, +Y upの3D空間において、手前に5mの位置から奥に向かって透視投影する場合
中心が0・縦横比が1のスクリーン座標 p を用いて、以下のように書ける
code:glsl
vec3 ro = vec3(0.0, 0.0, 5.0);
vec3 rd = normalize(vec3(p, -1.0));
平行投影
p を使って始点を動かすことによって、平行投影もできるよ
code:glsl
vec3 ro = vec3(p, 5.0);
vec3 rd = vec3(0.0, 0.0, -1.0);
魚眼レンズ
魚眼レンズのような射影も割と簡単にできるよ
以下は、等立体角射影方式の場合の例
他の射影方式については、各ページを参照
code:glsl
const float f = 1.0;
float r = length(p);
float theta = 2.0 * asin(r / f / 2.0);
vec3 rd = vec3(sin(theta) * p / r, -cos(theta));
Field of View
レイトレーシング・レイマーチングにおいてレイの向きを決めるとき、スクリーン座標 p が$ (-1, 1)の範囲の場合、以下のコードはFOV (Field of View、視野角) を90°とする:
code:glsl
rd = normalize(vec3(p, -1.0));
FOVを使う
視野角 FOV (弧度法) を設定したい場合、以下のようなコードになるよ
code:glsl
rd = normalize(vec3(p * tan(FOV / 2.0), -1.0));
sizecoding
sizecoding・Live Codingの場合、以下のようにZの値をスケールさせてFOVを調整することが多いと思う
code:glsl
rd = normalize(vec3(p, -2.0));
このとき、
$ FOV = 2 \ {\rm atan} \left( - \frac{1}{z} \right)
主なZ値ごとのFOVは以下のようになる
table:fov
z fov
-0.5 126.9 °
-1.0 90.0 °
-1.5 67.4 °
-2.0 53.1 °
-2.5 43.6 °
-3.0 36.9 °
-4.0 28.1 °
-5.0 22.6 °
code:js
-0.5, -1.0, -1.5, -2.0, -2.5, -3.0, -4.0, -5.0
.map((z) => {
const rad = 2.0 * Math.atan(-1 / z);
const deg = rad / Math.PI * 180.0;
const degDisplay = deg.toFixed(1);
return z, degDisplay;
})
35mm換算だと、-3.0が35mm (37.8°) に結構近いし、-4.0が50mm (27.0°) に結構近い